package orbito.physics.collision;

import java.awt.Polygon;

import orbito.util.Vec2;

public class CollidingPolygon {
	Vec2[] edgeNormals;
	Vec2[] points;
	
	Polygon drawablePolygon;
	
	public CollidingPolygon(Vec2[] points) {
		if (points.length < 3) {
			throw new IllegalArgumentException("A colliding polygon must consist of at least 3 points.");
		}
		
		this.points = points;
		this.edgeNormals = new Vec2[points.length];
		this.drawablePolygon = new Polygon();
		
		edgeNormals[0] = points[0].sub(points[points.length-1]).inormal().iunit();
		drawablePolygon.addPoint((int) points[0].x, (int) points[0].y);
		
		for (int i = 1; i < points.length; i++) {
			edgeNormals[i] = points[i].sub(points[i-1]).inormal().iunit();
			drawablePolygon.addPoint((int) points[i].x, (int) points[i].y);
		}
	}
	
	public Interval projectOntoAxis(Vec2 axis) {
		double dotProduct = Vec2.dot(points[0], axis);
		double min = dotProduct, max = dotProduct;
		
		for (int i = 0; i < points.length; i++) {
			dotProduct = Vec2.dot(points[i], axis);
			if (dotProduct < min) {
				min = dotProduct;
			} else if (dotProduct > max) {
				max = dotProduct;
			}
		}
		
		return new Interval(min, max);
	}
	
	public Polygon getDrawablePolygon() {
		return drawablePolygon;
	}
	
	public boolean intersects(double t, double dt, CollidingPolygon other, CollisionResult result) {
		double minInterDist = Double.POSITIVE_INFINITY;
		
		result.isIntersecting = true;
		result.minimumTranslationVector = null;
		
		for (int edgeIndex = 0; edgeIndex < edgeNormals.length; edgeIndex++) {
			Vec2 axis = edgeNormals[edgeIndex];
			
			// Project polygons onto the axis.
			Interval window1 = this.projectOntoAxis(axis);
			Interval window2 = other.projectOntoAxis(axis);
			
			// Check if the intervals are overlapping.
			double interDist = window1.getDistance(window2);
			if (interDist > 0) {
				result.isIntersecting = false;
				return false;
			} else {
				interDist = -interDist;
				if (interDist < minInterDist) {
					minInterDist = interDist;
					result.minimumTranslationVector = axis.mul(interDist);
				}
			}
		}
		
		return true;
	}
}
